
#ifndef CONNECTION_H
#define CONNECTION_H

#include <QUdpSocket>
#include <QStringList>
#include <QTimer>

#include "packet.h"
#include "packetdata.h"

class Connection : public QUdpSocket
{
    Q_OBJECT
public:
    Connection(QHostAddress a, quint16 p, bool onlyReceive = false);
    Connection(bool onlyReceive = false);

    //funkcja wywoluje bind() co pozwala obiektowi na odbieranie pakietow na zadanym porcie
    void connToHost();
    void disconnFromHost();

    void flushSendQueue();

    QString getHostPortKey();

    void setAddress(QHostAddress addr);
    void setPort(quint16);

    void setOnlyReceive(bool onr);

    void sendPacket(Packet* packet);
    void queuePacket(Packet* packet);
    void sendPacket(const QByteArray data, bool reliable = false, bool queuePacket = false);
    void sendPacket(PacketData* data, bool reliable = false, bool queuePacket = false);

    void startConnectionTimer(bool st);

    QAbstractSocket::SocketState getConnectionState();

protected:
    QAbstractSocket::SocketState connectionState;
    QTimer *timer;
    quint32 remote_sequence;
private:

    quint16 tickNr;

    QHostAddress address;
    quint16 port;
    quint16 bindPort;

    bool onlyReceive;

    quint32 lastPacketTime;

    bool isLocalhostAddr();

    quint32 sequence;


    QVector<Packet*> reliableSendList;
    QVector<Packet*> receiveList;
    QVector<Packet*> sendQueue;

signals:
    void newPacket(Packet* packet);
    void connectionStateChanged(QAbstractSocket::SocketState st);

public slots:
    virtual void processPacket(Packet* packet);
    virtual void runCommand(PacketData* data, bool isNewestPacket);

private slots:
    void onNewDatagram();
    void packetCleanup();



};

#endif // CONNECTION_H
